package com.trailwalker.traceability.activity;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.trailwalker.JavaUtils.DateUtils.DateUtils;
import com.trailwalker.JavaUtils.log.LogUtils;
import com.trailwalker.JavaUtils.string.StringUtils;
import com.trailwalker.javafx.utils.style.StyleUtils;
import com.trailwalker.javafx.utils.thread.ThreadUtils;
import com.trailwalker.traceability.entitiy.body.ProcessRequestBody;
import com.trailwalker.traceability.entitiy.body.ProcessResponseBody;
import com.trailwalker.traceability.entitiy.body.Semi;
import com.trailwalker.traceability.entitiy.body.WorkerListResponseBody;
import com.trailwalker.traceability.entitiy.enum_entity.ProcessType;
import com.trailwalker.traceability.service.ApiDataService;
import com.trailwalker.traceability.service.ExcelService;
import com.trailwalker.traceability.util.JfxUtils;
import com.trailwalker.traceability.widget.control.textfield.ScanTextFiled;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.InputMethodRequests;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import javafx.util.Callback;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Trailwalker
 * @create 2021-11-12 13:05
 */
public class SemiFinishedProductTestActivity extends BaseActivity {

    private static final String TAG = SemiFinishedProductTestActivity.class.getSimpleName();

    private AnchorPane mApContent;
    private Button mBtnImport;
    private ObservableList<String> mWorkerList;
    private ScanTextFiled mTfId;
    private ObservableList<Semi> mSemiList;
    private TableView<Semi> mTvSemiList;
    private int mLastScanedCodeListSize;
    private ObservableList<String> mScanedCodeList;
    private ListView<String> mLvScanedCode;

    @Override
    protected void afterSuperCreate() {
        initLoad();
        initView();
        initData();
        initListener();
        onReady();
    }

    private void onReady() {
        getWorkerList();
    }

    private void getWorkerList() {
        ApiDataService.getInstance().getWorkerList(mApplication, new Consumer<WorkerListResponseBody>() {
            @Override
            public void accept(WorkerListResponseBody workerListResponseBody) throws Exception {
                if (workerListResponseBody != null) {
                    mWorkerList = FXCollections.observableArrayList(workerListResponseBody.getRows());
                    mBtnImport.setDisable(false);
                }
            }
        });
    }

    private void initListener() {

        if (mTfId != null) {
            mTfId.setOnScanFinishedListener(new ScanTextFiled.OnScanFinishedListener() {
                @Override
                public void onFinish(String value) {
                    if (StringUtils.isValid(value)) {
                        check(value, new Action() {
                            @Override
                            public void run() throws Exception {
                                trace();
                            }
                        });
                    }
                }
            });
        }

        if (mBtnImport != null) {
            mBtnImport.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.getButton().equals(MouseButton.PRIMARY)) {
                        FileChooser fileChooser = new FileChooser();
                        FileChooser.ExtensionFilter extensionFilter = new FileChooser.ExtensionFilter("Excel", "*.xls", "*.xlsx");
                        fileChooser.getExtensionFilters().add(extensionFilter);
                        File file = fileChooser.showOpenDialog(mApplication.getStage());
                        if (file != null) {
                            mSemiList.clear();
                            ThreadUtils.runOnChildThread(new Runnable() {
                                @Override
                                public void run() {
                                    String date = DateUtils.getDate("yyyy-MM-dd HH:mm:ss");
                                    ExcelService.read(file, Semi.class, new AnalysisEventListener<Semi>() {
                                        @Override
                                        public void invoke(Semi data, AnalysisContext context) {
                                            ThreadUtils.runOnUiThread(new Runnable() {
                                                @Override
                                                public void run() {
                                                    data.setCreateTime(date);
                                                    mSemiList.add(data);
                                                }
                                            });
                                        }

                                        @Override
                                        public void doAfterAllAnalysed(AnalysisContext context) {
                                            ThreadUtils.runOnUiThread(new Runnable() {
                                                @Override
                                                public void run() {
                                                    mTvSemiList.requestFocus();
                                                    JfxUtils.showShortToast(mApplication.getStage(), "导入成功");
                                                }
                                            });
                                        }
                                    });
                                }
                            });
                        }
                    }
                }
            });
        }
    }

    private void check(String value, Action onCheckSuccess) {
        mTfId.clear();
        ProcessRequestBody processRequestBody = new ProcessRequestBody();
        processRequestBody.setProNum(value);
        processRequestBody.setProcessName(ProcessType.SEMI_FINISHED_PRODUCT_TEST.getName());
        ApiDataService.getInstance().check(mApplication, processRequestBody, new Consumer<ProcessResponseBody>() {
            @Override
            public void accept(ProcessResponseBody processResponseBody) throws Exception {
                mTfId.setText(value);
                String date = DateUtils.getDate("yyyy-MM-dd HH:mm:ss");
                for (int i = 0; i < mSemiList.size(); i++) {
                    Semi semi = mSemiList.get(i);
                    semi.setCreateTime(date);
                }
                mTvSemiList.refresh();
                if (onCheckSuccess != null) {
                    onCheckSuccess.run();
                }
            }
        });
    }

    private void trace() {
        if (validate()) {
            String id = mTfId.getText();
            ProcessRequestBody processRequestBody = new ProcessRequestBody();
            processRequestBody.setProNum(id);
            processRequestBody.setProcessName(ProcessType.SEMI_FINISHED_PRODUCT_TEST.getName());
            processRequestBody.setSemiList(mSemiList);
            ApiDataService.getInstance().trace(mApplication, processRequestBody, new Consumer<ProcessResponseBody>() {
                @Override
                public void accept(ProcessResponseBody processResponseBody) throws Exception {
                    mTfId.clear();
                    mTfId.requestFocus();
                    addScanedCode(id);
                }
            });
        } else {
            JfxUtils.showShortToast(mApplication.getStage(), "请输入正确的数据");
        }
    }

    private void addScanedCode(String id) {
        if (mScanedCodeList.size() >= mLastScanedCodeListSize) {
            mScanedCodeList.remove(0);
        }
        mScanedCodeList.add(id);
        mLvScanedCode.scrollTo(mScanedCodeList.size() - 1);
    }

    private boolean validate() {
        String id = mTfId.getText();
        if (StringUtils.isEmpty(id)) {
            return false;
        }
        return true;
    }

    private void initData() {

    }

    private void initView() {
        BorderPane bpContent = new BorderPane();
        mApContent.getChildren().add(bpContent);
        mAdaptUtils.setMatchParentAnchorPane(bpContent);

        HBox hbTitle = new HBox();
        bpContent.setTop(hbTitle);
        hbTitle.setAlignment(Pos.CENTER);
        mAdaptUtils.setScaleHeight(hbTitle, 150);

        Label lblTitle = new Label();
        hbTitle.getChildren().add(lblTitle);
        lblTitle.setText(ProcessType.SEMI_FINISHED_PRODUCT_TEST.getName());
        mAdaptUtils.setScaleTextSize(lblTitle, 40);
        StyleUtils.setTextColor(lblTitle, "#000000");

        initCenterView(bpContent);

        initRightView(bpContent);
    }

    private void initRightView(BorderPane bpContent) {
        BorderPane bpRight = new BorderPane();
        bpContent.setRight(bpRight);
        AnchorPane.setTopAnchor(bpRight, 0.0);
        AnchorPane.setRightAnchor(bpRight, 0.0);
        AnchorPane.setBottomAnchor(bpRight, 0.0);
        StyleUtils.setBackgroundColor(bpRight, "#f2f2f2");

        mAdaptUtils.setScaleWidth(bpRight, 350);

        HBox hbRightTitle = new HBox();
        bpRight.setTop(hbRightTitle);
        hbRightTitle.setAlignment(Pos.CENTER);
        mAdaptUtils.setScaleHeight(hbRightTitle, 60);

        Label mLblRightTitle = new Label();
        hbRightTitle.getChildren().add(mLblRightTitle);
        mLblRightTitle.setText("已完成产品id列表(最近" + mLastScanedCodeListSize + "个)");
        StyleUtils.setTextColor(mLblRightTitle, "#000000");
        mAdaptUtils.setScaleTextSize(mLblRightTitle, 25);

        mLvScanedCode = new ListView<>(mScanedCodeList);
        bpRight.setCenter(mLvScanedCode);
        mLvScanedCode.setPadding(javafx.geometry.Insets.EMPTY);
        mLvScanedCode.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
            @Override
            public ListCell<String> call(ListView<String> param) {

                ListCell<String> listCell = new ListCell<String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        HBox hbItemContainer = new HBox();
                        mAdaptUtils.setScaleHeight(hbItemContainer, 40);
                        hbItemContainer.setAlignment(Pos.CENTER);

                        if (!empty) {
                            HBox hbIdContainer = new HBox();
                            hbItemContainer.getChildren().add(hbIdContainer);
                            hbIdContainer.setAlignment(Pos.CENTER);
                            HBox.setHgrow(hbIdContainer, Priority.ALWAYS);

                            Label lblId = new Label();
                            hbIdContainer.getChildren().add(lblId);
                            StyleUtils.setTextColor(lblId, "#000000");
                            mAdaptUtils.setScaleTextSize(lblId, 25);
                            lblId.setText(item);
                        }

                        this.setGraphic(hbItemContainer);
                    }
                };
                listCell.setPadding(Insets.EMPTY);
                return listCell;
            }
        });
    }

    private void initCenterView(BorderPane bpContent) {
        VBox vbCenter = new VBox();
        bpContent.setCenter(vbCenter);
        vbCenter.setAlignment(Pos.CENTER);

        HBox hbIdContainer = new HBox();
        vbCenter.getChildren().add(hbIdContainer);
        hbIdContainer.setAlignment(Pos.CENTER);
        hbIdContainer.setSpacing(mAdaptUtils.getScale(20));

        Label lblId = new Label();
        hbIdContainer.getChildren().add(lblId);
        lblId.setText("ID:");
        StyleUtils.setTextColor(lblId, "#000000");
        mAdaptUtils.setScaleTextSize(lblId, 25);

        mTfId = new ScanTextFiled();
        hbIdContainer.getChildren().add(mTfId);
        mAdaptUtils.setScaleWidth(mTfId, 400);

        HBox hbBtnImportContainer = new HBox();
        vbCenter.getChildren().add(hbBtnImportContainer);
        hbBtnImportContainer.setAlignment(Pos.CENTER_RIGHT);
        mAdaptUtils.setScalePaddingTop(hbBtnImportContainer, 30);
        mAdaptUtils.setScalePaddingRight(hbBtnImportContainer, 120);

        mBtnImport = new Button();
        hbBtnImportContainer.getChildren().add(mBtnImport);
        StyleUtils.setBackgroundColor(mBtnImport, "#ffba00");
        mAdaptUtils.setScaleSize(mBtnImport, 100, 50);
        StyleUtils.setBorderRadius(mBtnImport, mAdaptUtils.getScale(100), mAdaptUtils.getScale(50), mAdaptUtils.getScale(10));
        mBtnImport.setCursor(Cursor.HAND);
        mAdaptUtils.setScaleTextSize(mBtnImport, 20);
        mBtnImport.setText("导入");
        StyleUtils.setTextColor(mBtnImport, "#ffffff");
        mBtnImport.setDisable(true);

        HBox hbTvContainer = new HBox();
        vbCenter.getChildren().add(hbTvContainer);
        hbTvContainer.setAlignment(Pos.CENTER);
        VBox.setMargin(hbTvContainer, mAdaptUtils.getMarginTop(30, VBox.getMargin(hbTvContainer)));
        mAdaptUtils.setScaleSize(hbTvContainer, 800, 350);

        mTvSemiList = new TableView<>(mSemiList);
        hbTvContainer.getChildren().add(mTvSemiList);
        mTvSemiList.prefWidthProperty().bind(hbTvContainer.widthProperty());
        mTvSemiList.prefHeightProperty().bind(hbTvContainer.heightProperty());
        //tvSemiList.setPlaceholder(null);
        mTvSemiList.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
        mTvSemiList.setEditable(false);
        mTvSemiList.setTableMenuButtonVisible(false);

        TableColumn<Semi, String> tcIndex = new TableColumn<>("工序编号");
        mTvSemiList.getColumns().add(tcIndex);
        tcIndex.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Semi, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Semi, String> param) {
                SimpleStringProperty simpleStringProperty = new SimpleStringProperty(param.getValue().getIndex());
                return simpleStringProperty;
            }
        });
        tcIndex.setCellFactory(new Callback<TableColumn<Semi, String>, TableCell<Semi, String>>() {
            @Override
            public TableCell<Semi, String> call(TableColumn<Semi, String> param) {
                TableCell<Semi, String> tableCell = new TableCell<Semi, String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        if (!empty) {
                            HBox hbItemContainer = new HBox();
                            hbItemContainer.setAlignment(Pos.CENTER);

                            Label label = new Label();
                            hbItemContainer.getChildren().add(label);
                            label.setText(item);
                            StyleUtils.setTextColor(label, "#000000");

                            this.setGraphic(hbItemContainer);
                        } else {
                            this.setGraphic(null);
                        }

                    }
                };
                return tableCell;
            }
        });

        TableColumn<Semi, String> tcProcessName = new TableColumn<>("工序名称");
        mTvSemiList.getColumns().add(tcProcessName);
        tcProcessName.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Semi, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Semi, String> param) {
                SimpleStringProperty simpleStringProperty = new SimpleStringProperty(param.getValue().getProcessName());
                return simpleStringProperty;
            }
        });
        tcProcessName.setCellFactory(new Callback<TableColumn<Semi, String>, TableCell<Semi, String>>() {
            @Override
            public TableCell<Semi, String> call(TableColumn<Semi, String> param) {
                TableCell<Semi, String> tableCell = new TableCell<Semi, String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        if (!empty) {
                            HBox hbItemContainer = new HBox();
                            hbItemContainer.setAlignment(Pos.CENTER);

                            Label label = new Label();
                            hbItemContainer.getChildren().add(label);
                            label.setText(item);
                            StyleUtils.setTextColor(label, "#000000");

                            this.setGraphic(hbItemContainer);
                        } else {
                            this.setGraphic(null);
                        }

                    }
                };
                return tableCell;
            }
        });

        TableColumn<Semi, String> tcCreateTime = new TableColumn<>("操作时间");
        mTvSemiList.getColumns().add(tcCreateTime);
        tcCreateTime.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Semi, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Semi, String> param) {
                SimpleStringProperty simpleStringProperty = new SimpleStringProperty(param.getValue().getCreateTime());
                return simpleStringProperty;
            }
        });
        tcCreateTime.setCellFactory(new Callback<TableColumn<Semi, String>, TableCell<Semi, String>>() {
            @Override
            public TableCell<Semi, String> call(TableColumn<Semi, String> param) {
                TableCell<Semi, String> tableCell = new TableCell<Semi, String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        if (!empty) {
                            HBox hbItemContainer = new HBox();
                            hbItemContainer.setAlignment(Pos.CENTER);

                            Label label = new Label();
                            hbItemContainer.getChildren().add(label);
                            label.setText(item);
                            StyleUtils.setTextColor(label, "#000000");

                            this.setGraphic(hbItemContainer);
                        } else {
                            this.setGraphic(null);
                        }

                    }
                };
                return tableCell;
            }
        });

        TableColumn<Semi, String> tcWorkerName = new TableColumn<>("操作人");
        mTvSemiList.getColumns().add(tcWorkerName);
        tcWorkerName.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Semi, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Semi, String> param) {
                SimpleStringProperty simpleStringProperty = new SimpleStringProperty(param.getValue().getWorkerName());
                return simpleStringProperty;
            }
        });
        tcWorkerName.setCellFactory(new Callback<TableColumn<Semi, String>, TableCell<Semi, String>>() {
            @Override
            public TableCell<Semi, String> call(TableColumn<Semi, String> param) {
                TableCell<Semi, String> tableCell = new TableCell<Semi, String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        if (!empty) {
                            HBox hbItemContainer = new HBox();
                            hbItemContainer.setAlignment(Pos.CENTER);

                            ComboBox<String> cbbWorkerName = new ComboBox<>();
                            hbItemContainer.getChildren().add(cbbWorkerName);
                            cbbWorkerName.setItems(mWorkerList);
                            if (item != null) {
                                cbbWorkerName.getSelectionModel().select(item);
                            }
                            cbbWorkerName.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
                                @Override
                                public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                                    Semi semi = mSemiList.get(getTableRow().getIndex());
                                    semi.setWorkerName(newValue);
                                    mTvSemiList.refresh();
                                }
                            });

                            this.setGraphic(hbItemContainer);
                        } else {
                            this.setGraphic(null);
                        }

                    }
                };
                return tableCell;
            }
        });

        TableColumn<Semi, String> tcRemark = new TableColumn<>("备注");
        mTvSemiList.getColumns().add(tcRemark);
        tcRemark.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Semi, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Semi, String> param) {
                SimpleStringProperty simpleStringProperty = new SimpleStringProperty(param.getValue().getRemark());
                return simpleStringProperty;
            }
        });
        tcRemark.setCellFactory(new Callback<TableColumn<Semi, String>, TableCell<Semi, String>>() {
            @Override
            public TableCell<Semi, String> call(TableColumn<Semi, String> param) {
                TableCell<Semi, String> tableCell = new TableCell<Semi, String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        if (!empty) {
                            HBox hbItemContainer = new HBox();
                            hbItemContainer.setAlignment(Pos.CENTER);

                            Label label = new Label();
                            hbItemContainer.getChildren().add(label);
                            label.setText(item);
                            StyleUtils.setTextColor(label, "#000000");
                            label.setTooltip(new Tooltip(item));

                            this.setGraphic(hbItemContainer);
                        } else {
                            this.setGraphic(null);
                        }

                    }
                };
                return tableCell;
            }
        });

    }

    private void initLoad() {
        mSemiList = FXCollections.observableArrayList();
        mScanedCodeList = FXCollections.observableArrayList();
        mLastScanedCodeListSize = mApplication.getConfig().getLastScanedCodeListSize(5);
    }

    @Override
    protected Node initContentView() {
        mApContent = new AnchorPane();
        return mApContent;
    }
}
